<?php

class color
{
	var $L = 0.0;
	var $a = 0.0;
	var $b = 0.0;

	function __construct($L=0.0, $a=0.0, $b=0.0)
	{
		$this->BLab($L, $a, $b);
	}

	function hexRGB($hex=null)
	{
		if (isset($hex)) {
			$R = intval(substr($hex, 0, 2), 16)/255;
			$G = intval(substr($hex, 2, 2), 16)/255;
			$B = intval(substr($hex, 4, 2), 16)/255;
			return $this->RGB($R, $G, $B);
		} else {
			list($R, $G, $B) = $this->RGB();
			$R *= 255;
			$G *= 255;
			$B *= 255;
			$R = $R>255 ? 255 : $R<0 ? 0 : $R;
			$G = $G>255 ? 255 : $G<0 ? 0 : $G;
			$B = $B>255 ? 255 : $B<0 ? 0 : $B;
			return sprintf('%02X', $R).sprintf('%02X', $G).sprintf('%02X', $B);
		}
	}

	function XYZ($X=null, $Y=0.0, $Z=0.0)
	{
		if (isset($X)) {
			if (is_array($X)) {
				$Y = $X[1];
				$Z = $X[2];
				$X = $X[0];
			}
			$X = $X>1 ? 1 : $X<0 ? 0 : $X;
			$Y = $Y>1 ? 1 : $Y<0 ? 0 : $Y;
			$Z = $Z>1 ? 1 : $Z<0 ? 0 : $Z;
			list($this->L, $this->a, $this->b) = self::LMS2BLab(self::RGB2LMS(self::XYZ2RGB($X, $Y, $Z)));
			return $this;
		} else {
			return self::RGB2XYZ(self::LMS2RGB(self::BLab2LMS($this->L, $this->a, $this->b)));
		}
	}

	function RGB($R=null, $G=0.0, $B=0.0)
	{
		if (isset($R)) {
			if (is_array($R)) {
				$G = $R[1];
				$B = $R[2];
				$R = $R[0];
			}
			$R = $R>1 ? 1 : $R<0 ? 0 : $R;
			$G = $G>1 ? 1 : $G<0 ? 0 : $G;
			$B = $B>1 ? 1 : $B<0 ? 0 : $B;
			list($this->L, $this->a, $this->b) = self::LMS2BLab(self::RGB2LMS($R, $G, $B));
			return $this;
		} else {
			return self::LMS2RGB(self::BLab2LMS($this->L, $this->a, $this->b));
		}
	}

	function LMS($L=null, $M=0.0, $S=0.0)
	{
		if (isset($L)) {
			if (is_array($L)) {
				$M = $L[1];
				$S = $L[2];
				$L = $L[0];
			}
			$L = $L>1 ? 1 : $L<0 ? 0 : $L;
			$M = $M>1 ? 1 : $M<0 ? 0 : $M;
			$S = $S>1 ? 1 : $S<0 ? 0 : $S;
			list($this->L, $this->a, $this->b) = self::LMS2BLab($L, $M, $S);
			return $this;
		} else {
			return elf::BLab2LMS($this->L, $this->a, $this->b);
		}
	}

	function BLab($L=null, $a=0.0, $b=0.0)
	{
		if (isset($L)) {
			if (is_array($L)) {
				$a = $L[1];
				$b = $L[2];
				$L = $L[0];
			}
			$this->L = $L;
			$this->a = $a;
			$this->b = $b;
			return $this;
		} else {
			return array($this->L, $this->a, $this->b);
		}
	}

	static function LMS2RGB($L, $M=0.0, $S=0.0)
	{
		if (is_array($L)) {
			$M = $L[1];
			$S = $L[2];
			$L = $L[0];
		}
		$L = $L>1 ? 1 : $L<0 ? 0 : $L;
		$M = $M>1 ? 1 : $M<0 ? 0 : $M;
		$S = $S>1 ? 1 : $S<0 ? 0 : $S;

		$R =  4.4679*$L - 3.5873*$M + 0.1193*$S;
		$G = -1.2186*$L + 2.3809*$M - 0.1624*$S;
		$B =  0.0497*$L - 0.2439*$M + 1.2045*$S;

		$R = $R>1 ? 1 : $R<0 ? 0 : $R;
		$G = $G>1 ? 1 : $G<0 ? 0 : $G;
		$B = $B>1 ? 1 : $B<0 ? 0 : $B;

		return array ($R, $G, $B);
	}

	static function XYZ2RGB($X, $Y=0.0, $Z=0.0)
	{
		if (is_array($X)) {
			$Y = $X[1];
			$Z = $X[2];
			$X = $X[0];
		}
		$X = $X>1 ? 1 : $X<0 ? 0 : $X;
		$Y = $Y>1 ? 1 : $Y<0 ? 0 : $Y;
		$Z = $Z>1 ? 1 : $Z<0 ? 0 : $Z;

		$R =  3.063*$X - 1.393*$Y - 0.476*$Z;
		$G = -0.969*$X + 1.876*$Y + 0.042*$Z;
		$B =  0.068*$X - 0.229*$Y + 1.069*$Z;

		$R = $R>1 ? 1 : $R<0 ? 0 : $R;
		$G = $G>1 ? 1 : $G<0 ? 0 : $G;
		$B = $B>1 ? 1 : $B<0 ? 0 : $B;

		return array ($R, $G, $B);
	}

	static function RGB2XYZ($R, $G=0.0, $B=0.0)
	{
		if (is_array($R)) {
			$G = $R[1];
			$B = $R[2];
			$R = $R[0];
		}

		$R = $R>1 ? 1 : $R<0 ? 0 : $R;
		$G = $G>1 ? 1 : $G<0 ? 0 : $G;
		$B = $B>1 ? 1 : $B<0 ? 0 : $B;

		$X = 0.431*$R + 0.342*$G + 0.178*$B;
		$Y = 0.222*$R + 0.707*$G + 0.071*$B;
		$Z = 0.020*$R + 0.130*$G + 0.939*$B;

		$X = $X>1 ? 1 : $X<0 ? 0 : $X;
		$Y = $Y>1 ? 1 : $Y<0 ? 0 : $Y;
		$Z = $Z>1 ? 1 : $Z<0 ? 0 : $Z;

		return array ($X, $Y, $Z);
	}

	static function RGB2LMS($R, $G=0.0, $B=0.0)
	{
		if (is_array($R)) {
			$G = $R[1];
			$B = $R[2];
			$R = $R[0];
		}

		$R = $R>1 ? 1 : $R<0 ? 0 : $R;
		$G = $G>1 ? 1 : $G<0 ? 0 : $G;
		$B = $B>1 ? 1 : $B<0 ? 0 : $B;

		$L = 0.3811*$R + 0.5783*$G + 0.0402*$B;
		$M = 0.1967*$R + 0.7244*$G + 0.0782*$B;
		$S = 0.0241*$R + 0.1288*$G + 0.8444*$B;

		$L = $L>1 ? 1 : $L<0 ? 0 : $L;
		$M = $M>1 ? 1 : $M<0 ? 0 : $M;
		$S = $S>1 ? 1 : $S<0 ? 0 : $S;

		return array ($L, $M, $S);
	}

	static function LMS2BLab($L, $M=0.0, $S=0.0)
	{
		if (is_array($L)) {
			$M = $L[1];
			$S = $L[2];
			$L = $L[0];
		}
		$L = $L>1 ? 1 : $L<0 ? 0 : $L;
		$M = $M>1 ? 1 : $M<0 ? 0 : $M;
		$S = $S>1 ? 1 : $S<0 ? 0 : $S;

		$lgL = log10($L);
		$lgM = log10($M);
		$lgS = log10($S);

		$L = 0.5774*$lgL + 0.5774*$lgM + 0.5774*$lgS;
		$a = 0.4082*$lgL + 0.4082*$lgM - 2*0.4082*$lgS;
		$b = 0.7071*$lgL - 0.7071*$lgM + 0.0000*$lgS;

		return array ($L, $a, $b);
	}

	static function BLab2LMS($L, $a=0.0, $b=0.0)
	{
		if (is_array($L)) {
			$a = $L[1];
			$b = $L[2];
			$L = $L[0];
		}
		$_L = 0.5774*$L + 0.4082*$a + 0.7071*$b;
		$_M = 0.5774*$L + 0.4082*$a - 0.7071*$b;
		$_S = 0.5774*$L - 2*0.4082*$a + 0.0000*$b;

		$L = pow(10, $_L);
		$M = pow(10, $_M);
		$S = pow(10, $_S);

		$L = $L>1 ? 1 : $L<0 ? 0 : $L;
		$M = $M>1 ? 1 : $M<0 ? 0 : $M;
		$S = $S>1 ? 1 : $S<0 ? 0 : $S;

		return array ($L, $M, $S);
	}

}

?>